﻿using HCMS.Const;
using HCMS.Extensions;
using HCMS.IServices.Manage;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Security.Claims;

namespace HCMS.Web.Manage.Filter
{
	/// <summary>
	/// 方法 权限校验 过滤器
	/// </summary>
	public class ActionAuthFilter : Attribute, IAsyncActionFilter
	{
		private readonly IRoleMenuAppService roleMenuAppService;

		public ActionAuthFilter(IRoleMenuAppService roleMenuAppService)
		{
			this.roleMenuAppService = roleMenuAppService;
		}

		/// <summary>
		/// 方法 执行之前 调用
		/// </summary>
		/// <param name="context"></param>
		/// <param name="next"></param>
		/// <returns></returns>
		/// <exception cref="NotImplementedException"></exception>
		public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
		{
			var endpointMetadata = context.ActionDescriptor.EndpointMetadata;

			bool hasAllowAnonymous = endpointMetadata.Any(em => em.GetType() == typeof(AllowAnonymousAttribute));
			if (hasAllowAnonymous)
			{
				// 允许匿名访问，不需要身份认证，就可以直接访问的方法
				await next();
				return;
			}

			if (context.HttpContext.User.Identity != null && !context.HttpContext.User.Identity.IsAuthenticated)
			{
				// 未登录，跳转到 登录页
				context.HttpContext.Response.Redirect("/auth/login/");
				return;
			}

			bool hasDefaultPermission = endpointMetadata.Any(em => em.GetType() == typeof(DefaultPermissionAttribute));
			if (hasDefaultPermission)
			{
				// 所有登录用户，默认拥有的权限。首页、退出登录
				await next();
				return;
			}

			// 超级管理员 拥有所有权限
			int roleId = context.HttpContext.User.FindFirstValue(ManageConst_ClaimTypes.RoleId).ToInt(0);
			if (roleId == ManageConst.SuperRoleId)
			{
				await next();
				return;
			}

			ControllerActionDescriptor? descriptor = context.ActionDescriptor as ControllerActionDescriptor;
			string currentControllerName = (descriptor?.ControllerName) ?? "";
			string currentActionName = (descriptor?.ActionName) ?? "";

			var menus = await roleMenuAppService.MenuListByRoleId(roleId);
			if (menus == null || !menus.Any())
			{
				// 已登录，无权限
				context.HttpContext.Response.Redirect("/auth/login/");
				return;
			}

			var isPass = menus.FirstOrDefault(t => t.ControllerName.ToUpper() == currentControllerName.ToUpper() && t.ActionName.ToUpper() == currentActionName.ToUpper());
			if (isPass == null)
			{
				// 没有当前 Action 访问权限，直接返回 403
				context.HttpContext.Response.StatusCode = 403;
				return;
			}

			await next();
		}
	}
}
